<?php
/**
 * 打包程序
 * @author Giles <giles.wang@icloud.com>
 *
 * **/
class codesign
{
    //证书
    public $mobileprovision = ''; //mobileprovision 文件
    public $certificate_str  = 'Jiangsu Hualong Continuous Cast Iron Co., Ltd.'; //证书字符串
    public $entitlements     = '';
    public $itermid ='';
    public $bundleId ='';
    public $workDir          = "runTemp";
    public $trueDir          = '';
    public $pack             = "";
    public $fileName         = '';
    public $bak = '';

    public function __construct($pack, $true)
    {
        $this->pack    = $pack;
        $this->trueDir = $true;
        $this->workDir = TRUE_PAK .'runTemp';
        $this->entitlements = ROOT_PATH. 'game.entitlements';
    }

    public function run()
    {

        if(empty($this->pack) || empty($this->trueDir)) {
            echo "路径错误";
            return array('error' => '1001', 'message' =>"包名不存在");
        }

        $fileInfo = pathinfo($this->pack);

        saveLog('强签开始:'. $fileInfo['filename']);

        echo $fileInfo['filename'] .".ipa --->任务开始". date('Y-m-d H:i:s'). "\n";

        if(is_dir($this->workDir)) {
            exec("rm -rf ".$this->workDir.'/');
        }

        exec("mkdir ". $this->workDir);
        exec("unzip -d ". $this->workDir ." ". $this->pack,  $ou, $status);
        if($status != 0 ) {
            exec("rm -rf ".$this->workDir.'/');
            return array('error' => '1002', 'message' =>"解压失败");
        }
        exec('cd  '. $this->workDir .' ;find Payload -type d -name "*.app" -o -name "*.appex" -o -name "*.framework"', $dirs);

        $list = $tmp = array();

        $fileInfo = pathinfo($this->pack);
        $filearry=explode("_",$fileInfo['filename']);
        echo $fileInfo['filename'] .".ipa --->任务创建中". date('Y-m-d H:i:s'). "\n";

        foreach($dirs as $dir) {
            $deep = count(explode("/", $dir));
            $tmp[$deep][] = $dir;
        }
        krsort($tmp);
        $md5cer      = md5($this->certificate_str);
        echo $md5cer;
       

        foreach($tmp as $deep => $deepdirs) {
            foreach($deepdirs as $deepdir) {
                $list[] = $deepdir;
            }
        }
        
      	echo "证书MD5 /n";
        echo $md5cer;

        saveLog('修改entitlements '.$fileInfo['filename']);
        exec("/usr/libexec/plistbuddy -c 'Set :application-identifier \"".$this->itermid .".". $this->bundleId ."\"' ". $this->entitlements);
        exec("/usr/libexec/plistbuddy -c 'Set :com.apple.developer.team-identifier \"". $this->itermid ."\"' " .$this->entitlements);
        exec("/usr/libexec/plistbuddy -c 'Set :keychain-access-groups:0 \"". $this->itermid .".*\"' ".$this->entitlements);


        exec('cd  '. $this->workDir .' ;find Payload -name "*.dylib"', $dylibs);

        echo $fileInfo['filename'] .".ipa --->进入动态库". date('Y-m-d H:i:s'). "\n";

        if(count($dylibs) > 0) {
            foreach($dylibs as $dylibs) {
                $signdirshell = str_replace(' ', '\ ', addslashes($this->workDir ."/". $dylibs));

                exec("/usr/bin/codesign --force --sign '" . $this->certificate_str .
                    "' --entitlements " . $this->entitlements . " " . $signdirshell, $output);
                echo $output;
                if (count($output) > 1) {
                    exec("rm -rf ".$this->workDir.'/');
                    return array('error' => '1005', 'message' =>"强签名失败");
                }
                if (strstr($output [0], 'no identity found')) {
                    exec("rm -rf ".$this->workDir.'/');
                    return array('error' => '1006', 'message' =>"no identity found");
                }
            }
        }


        foreach($list as $signdir) {
            $signdirshell = str_replace(' ', '\ ', addslashes($this->workDir ."/". $signdir));
            $isAdd = "/usr/libexec/plistbuddy -c 'Add :CerBundleID String \"". $md5cer ."|".$filearry['4']."\"' ". $signdirshell ."/Info.plist";
            exec($isAdd, $actions, $cobak);
			
			echo "修改entitlements".$cobak;
            if($cobak != 0) {
               $set = "/usr/libexec/plistbuddy -c 'Set :CerBundleID \"". $md5cer ."|".$filearry['4']."\"' ". $signdirshell ."/Info.plist";
               exec($set);
            }else{

               $set = "/usr/libexec/plistbuddy -c 'Set :CerBundleID \"". $md5cer ."|".$filearry['4']."\"' ". $signdirshell ."/Info.plist";
               exec($set);

            };
            echo "/usr/libexec/plistbuddy -c 'Set :CerBundleID \"". $md5cer ."|".$filearry['4']."\"' ". $signdirshell ."/Info.plist";
            
            exec("rm -rf " . $signdirshell . "/_CodeSignature;rm -rf " . $signdirshell . "/SC_Info;rm -rf " . $signdirshell .
                "/*.mobileprovision;rm -rf " . $signdirshell . "/KY_Channel.plist");

            exec("cp " .$this->mobileprovision . " " . $signdirshell . "/");
            exec("mv " . $signdirshell . "/" . basename($this->mobileprovision) . " " . $signdirshell . "/embedded.mobileprovision");

            exec("/usr/bin/codesign --force --sign '" . $this->certificate_str .
                "' --entitlements " . $this->entitlements . " --deep " . $signdirshell ." 2>&1 ", $output, $status);
            echo "/usr/bin/codesign --force --sign '" . $this->certificate_str . "' --entitlements " . $this->entitlements . " --deep " . $signdirshell;
            //echo $fileInfo['filename'] .".ipa --->修改entitlements".$output."状态".$status. "\n";

            if($status != 0){

                return array('error' => '1002', 'message' => '重签失败');
            };

            if (strstr($output [0], 'no identity found')) {
                exec("rm -rf ".$this->workDir.'/');
                return array('error' => '1008', 'message' => 'no identity found');
            }
        }


        exec("cd ". $this->workDir ." && zip -r temp.ipa ./*");
		
	
	    if(!$this->bak) {
            echo "备份包1";
            exec("mv " . $this->workDir . "/temp.ipa " . $this->trueDir . '/' .  $fileInfo['filename'] . '.true.ipa');
			echo "mv " . $this->workDir . "/temp.ipa " . $this->trueDir . '/' .  $fileInfo['filename'] . '.true.ipa';
			echo "\n";
			echo $this->trueDir . '/' .  $fileInfo['filename'] . '.true.ipa';
			$filemd5 = md5_file($this->trueDir . '/' .  $fileInfo['filename'] . '.true.ipa');
			
                     exec("rm -rf " . $this->workDir . '/');
            
			print_r($filemd5);
                     saveLog("文件名MD5",$filemd5);
		    $filearry=explode("_",$fileInfo['filename']);
		    print_r($filearry);
	            $fileNames = $filemd5 .'_'. $filearry['1']. '_' .$filearry['2'] .'_'.$filearry['3'].'_'.$filearry['4'];
		    echo $fileNames;
		   echo "\n";		echo  $this->trueDir . '/' . $fileNames.'.ipa.true.ipa';
			rename($this->trueDir . '/' .  $fileInfo['filename'] . '.true.ipa' , $this->trueDir . '/' . $fileNames.'.ipa.true.ipa') ;
			return array('error' => '0000', 'message' => $fileNames . '.ipa.true.ipa');
        }else{
            echo "备份包2";
            exec("mv " . $this->workDir . "/temp.ipa " . $this->trueDir . '/' .  $fileInfo['filename'].'.bak.ipa');
			$filemd5 = md5_file($this->trueDir . '/' .  $fileInfo['filename'] . '.bak.ipa');
			
             echo "\n";
			echo $this->trueDir . '/' .  $fileInfo['filename'] . '.bak.ipa';
			$filemd5 = md5_file($this->trueDir . '/' .  $fileInfo['filename'] . '.bak.ipa');
			
                     exec("rm -rf " . $this->workDir . '/');
            
			print_r($filemd5);
		    $filearry=explode("_",$fileInfo['filename']);
		    print_r($filearry);
	            $fileNames = $filemd5 .'_'. $filearry['1']. '_' .$filearry['2'] .'_'.$filearry['3'].'_'.$filearry['4'];
		    echo $fileNames;
		   echo "\n";		echo  $this->trueDir . '/' . $fileNames.'.ipa.bak.ipa';
			rename($this->trueDir . '/' .  $fileInfo['filename'] . '.bak.ipa' , $this->trueDir . '/' . $fileNames.'.ipa.bak.ipa') ;
			return array('error' => '0000', 'message' => $fileNames . '.ipa.bak.ipa');
           
        }
    }

}
       function strresin($packInfo, $perfileInfo,$bak){

       saveLog('进入任务:');
       exec('security unlock-keychain "-p" "jufeng123" /Users/pack/Library/Keychains/login.keychain');

       $file  = TRUE_PAK.$packInfo['packName'];
       $truePath =  $trueDir = TRUE_PAK.'strpsign';

       if(!is_dir($truePath)) {

           exec('mkdir '.$truePath);
           exec("chmod -R 777".$truePath);
       }
        return signCode($file,$truePath,$perfileInfo,$bak);

       }
    /**
     * 签名
     * @param $file 签名文件
     * @param $truePath 签名成功后的路径
     *
     */
    function signCode($file, $truePath,$certificate,$bak)
    {
        $file = str_replace('(', '\(', $file);
        $file = str_replace(')', '\)', $file);
        $file = str_replace(' ', '\ ', $file);
        $file = str_replace(';', '\;', $file);
        $file = str_replace('&', '\&', $file);
        $file = str_replace("'", <<<TAG
\'
TAG
            , $file);
        $codesign = new codesign($file, $truePath);


        $termId = $certificate['itermid'];
        $bundleId = $certificate['bundleId'];
        $pername  = $certificate['name'];
        $certificate = $certificate['perfileCertificate'];


        $codesign->itermid  =  $termId;
        $codesign->bundleId = $bundleId;
        $codesign->mobileprovision = PERFILE .$pername;

        $codesign->bak = $bak;

        $codesign->certificate_str = $certificate;

        return $codesign->run();

        unset($codesign);

    }

